#ifndef LOGUTIL_H
#define LOGUTIL_H

#include <QObject>
#include <QString>
#include <QMutex>
#include <QFile>
#include <QDateTime>
#include <QDir>

// 日志级别：按严重程度从低到高排序
enum class LogLevel {
    Debug,    // 调试信息（开发阶段用，如模块初始化）
    Info,     // 普通信息（用户操作、功能执行成功）
    Warning,  // 警告信息（非致命问题，如配置无效）
    Error,    // 错误信息（功能失败，如API请求失败）
    Critical  // 严重错误（系统崩溃、核心依赖加载失败）
};

class LogUtil : public QObject
{
    Q_OBJECT
    Q_DISABLE_COPY_MOVE(LogUtil)  // 禁止拷贝与移动，确保单例唯一性

public:
    // 单例接口：线程安全
    static LogUtil* getInstance(QObject* parent = nullptr);

    // 日志写入接口：支持不同级别+模块名+自定义信息
    void debug(const QString& module, const QString& message);
    void info(const QString& module, const QString& message);
    void warning(const QString& module, const QString& message);
    void error(const QString& module, const QString& message);
    void critical(const QString& module, const QString& message);

    // 设置日志文件路径（默认使用%APPDATA%/scSmartInput/log.txt）
    void setLogPath(const QString& path);

private:
    explicit LogUtil(QObject* parent = nullptr);
    ~LogUtil() override;

    // 私有核心方法：统一日志写入逻辑
    void writeLog(LogLevel level, const QString& module, const QString& message);
    // 格式化日志内容：[时间][级别][模块] 信息
    QString formatLog(LogLevel level, const QString& module, const QString& message);
    // 初始化日志文件：创建目录+文件（若不存在）
    bool initLogFile();

private:
    static LogUtil* m_instance;
    static QMutex m_instanceMutex;  // 单例线程安全锁
    QMutex m_writeMutex;            // 日志写入锁（避免多线程冲突）
    QFile m_logFile;                // 日志文件对象
    QString m_logPath;               // 日志文件路径
    const QString m_defaultDir = QDir::homePath() + "/AppData/Roaming/scSmartInput/";  // Windows默认目录
    const QString m_defaultFileName = "log.txt";
};

// 便捷宏定义：简化调用（无需重复传模块名）
#define LOG_DEBUG(module, msg) LogUtil::getInstance()->debug(module, msg)
#define LOG_INFO(module, msg) LogUtil::getInstance()->info(module, msg)
#define LOG_WARNING(module, msg) LogUtil::getInstance()->warning(module, msg)
#define LOG_ERROR(module, msg) LogUtil::getInstance()->error(module, msg)
#define LOG_CRITICAL(module, msg) LogUtil::getInstance()->critical(module, msg)

#endif  // LOGUTIL_H
